package reentlock;


import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class DemoReentryLock implements Lock {
    /**
     * 用来标记是否已经有线程获取了锁
     * 是的话 值为true 否则为 false
     */
    private boolean isHold = false;
    /**
     * 用来记录当前获取锁的线程
     */
    private Thread nowHoldThread = null;
    /**
     * 记录锁重入的次数
     */
    private int holdNum = 0;

    @Override
    public synchronized void lock() {
        /**
         * 判断是否已经有线程获取了锁，
         * 如果已经有人获取了锁，再判断当前操作锁的线程是不是获取了锁的线程
         */
        if (isHold && Thread.currentThread() != nowHoldThread) {
            //说明当前操作锁的线程，不是获取锁的线程，将当前线程挂起
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //没有人获取锁，或者被挂起的线程被唤醒了，将获取锁的线程，变成当前操作锁的线程
        nowHoldThread = Thread.currentThread();
        //将重入的次数加一，同时设置 标志位位true，表示锁已经被获取
        holdNum++;
        isHold = true;
    }

    @Override
    public synchronized void unlock() {
        //解锁的时候，首先判断当前操作的线程是不是获取了锁的线程
        if (Thread.currentThread() == nowHoldThread) {
            //将记录锁重入的次数 -1 ，在判断其值是不是0，是0说明重入的次数已经全部出来了，就可以通知其他线程来获取锁
            holdNum--;
            if (holdNum == 0) {
                isHold = false;
                notify();
            }
        }
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {

    }

    @Override
    public boolean tryLock() {
        return false;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return false;
    }


    @Override
    public Condition newCondition() {
        return null;
    }
}
